<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch">
      <el-form-item :label="$t('authRole.RoleName')" prop="roleName">
        <el-input v-model="queryParams.roleName" :placeholder="$t('role.InputRoleName')" clearable style="width: 240px"
          @keyup.enter.native="handleQuery" />
      </el-form-item>
      <el-form-item :label="$t('authRole.PermissionCharacter')" prop="roleKey">
        <el-input v-model="queryParams.roleKey" :placeholder="$t('role.PleaseEnterPermissionCharacters')" clearable
          style="width: 240px" @keyup.enter.native="handleQuery" />
      </el-form-item>
      <el-form-item :label="$t('index.State')" prop="status">
        <dict-select v-model="queryParams.status" :dict="dict.type.sys_normal_disable"
          :placeholder="$t('role.RoleState')" clearable style="width: 240px" />
      </el-form-item>
      <el-form-item :label="$t('user.CreateTime')">
        <el-date-picker v-model="dateRange" style="width: 240px" value-format="yyyy-MM-dd" type="daterange"
          range-separator="-" :start-placeholder="$t('user.StartTime')" :end-placeholder="$t('user.EndTime')">
        </el-date-picker>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">{{ $t("Search") }}</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">{{
          $t("Reset")
        }}</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
          v-hasPermi="['system:role:add']">{{ $t("Add") }}</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate"
          v-hasPermi="['system:role:edit']">{{ $t("Modify") }}</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete"
          v-hasPermi="['system:role:remove']">{{ $t("Delete") }}</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport"
          v-hasPermi="['system:role:export']">{{ $t("Export") }}</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>

    <el-table v-loading="loading" :data="roleList" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column :label="$t('authRole.RoleID')" prop="roleId" width="120" />
      <el-table-column :label="$t('authRole.RoleName')" prop="roleName" :show-overflow-tooltip="true" min-width="150" />
      <el-table-column :label="$t('authRole.PermissionCharacter')" prop="roleKey" :show-overflow-tooltip="true"
        width="155" />
      <el-table-column :label="$t('role.DisplayOrder')" prop="roleSort" width="110" />
      <el-table-column :label="$t('card.State')" align="center" width="100">
        <template slot-scope="scope">
          <el-switch v-model="scope.row.status" :active-value="0" :inactive-value="1"
            @change="handleStatusChange(scope.row)"></el-switch>
        </template>
      </el-table-column>
      <el-table-column :label="$t('card.State')" align="center" prop="createTime" width="180">
        <template slot-scope="scope">
          <span>{{ DateFormat(scope.row.createTime) }}</span>
        </template>
      </el-table-column>
      <el-table-column :label="$t('Operate')" align="center" class-name="small-padding fixed-width">
        <template slot-scope="scope" v-if="scope.row.roleId !== 1">
          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
            v-hasPermi="['system:role:edit']">{{ $t("Modify") }}</el-button>
          <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
            v-hasPermi="['system:role:remove']">{{ $t("Delete") }}</el-button>
          <el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)"
            v-hasPermi="['system:role:edit']">
            <span class="el-dropdown-link">
              <i class="el-icon-d-arrow-right el-icon--right"></i>{{ $t("user.More") }}
            </span>
            <el-dropdown-menu slot="dropdown">
              <el-dropdown-item command="handleDataScope" icon="el-icon-circle-check" v-hasPermi="['system:role:edit']">
                {{ $t("role.DataPermission") }}</el-dropdown-item>
              <!-- <el-dropdown-item command="handleAuthUser" icon="el-icon-user" v-hasPermi="['system:role:edit']">
                {{ $t("role.AssignUser") }}</el-dropdown-item> -->
            </el-dropdown-menu>
          </el-dropdown>
        </template>
      </el-table-column>
    </el-table>

    <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
      @pagination="getList" />

    <!-- 添加或修改角色配置对话框 -->
    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
      <el-form ref="form" :model="form" :rules="rules" label-width="100px">
        <el-form-item :label="$t('authRole.RoleName')" prop="roleName">
          <el-input v-model="form.roleName" :placeholder="$t('role.InputRoleName')" />
        </el-form-item>
        <el-form-item prop="roleKey">
          <span slot="label">
            <el-tooltip :content="$t('role.PermissionCharactersDefinedController')" placement="top">
              <i class="el-icon-question"></i>
            </el-tooltip>
            {{ $t("authRole.PermissionCharacter") }}
          </span>
          <el-input v-model="form.roleKey" :placeholder="$t('role.PleaseEnterPermissionCharacters')" />
        </el-form-item>
        <el-form-item :label="$t('role.RoleType')" prop="roleType">
          <el-select v-model="form.roleType">
            <el-option :value="0" label="管理角色"></el-option>
            <el-option :value="1" label="代理角色(设备)"></el-option>
            <el-option :value="2" label="人员角色"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item :label="$t('role.RoleOrder')" prop="roleSort">
          <el-input-number v-model="form.roleSort" controls-position="right" :min="0" />
        </el-form-item>
        <el-form-item :label="$t('card.State')">
          <dict-number-radio v-model="form.status" :dict="dict.type.sys_normal_disable" />
        </el-form-item>
        <el-form-item :label="$t('role.MenuPermissions')">
          <el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand($event, 'menu')">
            {{ $t("index.Unfold") }}/{{ $t("role.Fold") }}</el-checkbox>
          <el-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll($event, 'menu')">{{ $t("role.SelectALL") }}/{{
              $t("role.UnselectALL")
            }}</el-checkbox>
          <el-checkbox v-model="form.menuCheckStrictly" @change="handleCheckedTreeConnect($event, 'menu')">
            {{ $t("role.Parent-childLinkage") }}</el-checkbox>
          <el-tree class="tree-border" :data="menuOptions" show-checkbox ref="menuTree" node-key="id"
            :check-strictly="!form.menuCheckStrictly" :empty-text="$t('role.Loading')" :props="defaultProps"></el-tree>
        </el-form-item>
        <el-form-item :label="$t('user.Remarks')">
          <el-input v-model="form.remark" type="textarea" :placeholder="$t('user.InputContent')"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">{{
          $t("OK")
        }}</el-button>
        <el-button @click="cancel">{{ $t("Cancel") }}</el-button>
      </div>
    </el-dialog>

    <!-- 分配角色数据权限对话框 -->
    <el-dialog :title="title" :visible.sync="openDataScope" width="500px" append-to-body>
      <el-form :model="form" label-width="160px">
        <el-form-item :label="$t('authRole.RoleName')">
          <el-input v-model="form.roleName" :disabled="true" />
        </el-form-item>
        <el-form-item :label="$t('authRole.PermissionCharacter')">
          <el-input v-model="form.roleKey" :disabled="true" />
        </el-form-item>
        <el-form-item :label="$t('role.ScopeAuthorit')">
          <el-select v-model="form.dataScope" @change="dataScopeSelectChange">
            <el-option v-for="item in dataScopeOptions" :key="item.value" :label="item.label"
              :value="parseInt(item.value)">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item :label="$t('role.DataPermission')" v-show="form.dataScope == 2">
          <el-checkbox v-model="deptExpand" @change="handleCheckedTreeExpand($event, 'dept')">
            {{ $t("index.Unfold") }}/{{ $t("role.Fold") }}</el-checkbox>
          <el-checkbox v-model="deptNodeAll" @change="handleCheckedTreeNodeAll($event, 'dept')">{{ $t("role.SelectALL") }}/{{
              $t("role.UnselectALL")
            }}</el-checkbox>
          <el-checkbox v-model="form.deptCheckStrictly" @change="handleCheckedTreeConnect($event, 'dept')">
            {{ $t("role.Parent-childLinkage") }}</el-checkbox>
          <el-tree class="tree-border" :data="deptOptions" show-checkbox default-expand-all ref="dept" node-key="id"
            :check-strictly="!form.deptCheckStrictly" :empty-text="$t('role.Loading')" :props="defaultProps"></el-tree>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitDataScope">{{
          $t("OK")
        }}</el-button>
        <el-button @click="cancelDataScope">{{
          $t("Cancel")
        }}</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
  import {
    listRole,
    getRole,
    delRole,
    addRole,
    updateRole,
    dataScope,
    changeRoleStatus,
  } from "@/api/system/role";
  import {
    treeselect as menuTreeselect,
    roleMenuTreeselect,
  } from "@/api/system/menu";
  import {
    treeselect as deptTreeselect,
    roleTreeSelect,
  } from "@/api/system/dept";

  export default {
    name: "Role",
    dicts: ["sys_normal_disable"],
    data() {
      return {
        loading: true,
        ids: [],
        single: true,
        multiple: true,
        showSearch: true,
        total: 0,
        roleList: [],
        title: "",
        open: false,
        openDataScope: false,
        menuExpand: false,
        menuNodeAll: false,
        deptExpand: true,
        deptNodeAll: false,
        dateRange: [],
        dataScopeOptions: [{
            value: "1",
            label: this.$t("role.AllDataPermissions"),
          },
          {
            value: "2",
            label: this.$t("role.CustomizedDataPermission"),
          },
          {
            value: "3",
            label: this.$t("role.DataPermissionDepartment"),
          },
          {
            value: "4",
            label: this.$t("role.DataAuthorityDepartmentBelow"),
          },
          {
            value: "5",
            label: this.$t("role.OnlyOwnDataPermission"),
          },
        ],
        menuOptions: [],
        deptOptions: [],
        queryParams: {
          pageNum: 1,
          pageSize: 10,
          roleName: undefined,
          roleKey: undefined,
          status: undefined,
        },
        form: {},
        defaultProps: {
          children: "children",
          label: "label",
        },
        rules: {
          roleName: [{
            required: true,
            message: this.$t("role.RoleNameNULL"),
            trigger: "blur",
          }, ],
          roleKey: [{
            required: true,
            message: this.$t("role.PermissionCharacterNull"),
            trigger: "blur",
          }, ],
          roleType: [{
            required: true,
            message: '角色类型不能为空',
            trigger: "blur",
          }, ],
          roleSort: [{
            required: true,
            message: this.$t("role.RolesOrderNULL"),
            trigger: "blur",
          }, ],
        },
      };
    },
    created() {
      this.getList();
    },
    methods: {
      getList() {
        this.loading = true;
        listRole(this.addDateRange(this.queryParams, this.dateRange)).then(
          (response) => {
            this.roleList = response.rows;
            this.total = response.total;
            this.loading = false;
          }
        );
      },
      getMenuTreeselect() {
        menuTreeselect().then((response) => {
          this.menuOptions = response.data;
        });
      },
      getDeptTreeselect() {
        deptTreeselect().then((response) => {
          this.deptOptions = response.data;
        });
      },
      getMenuAllCheckedKeys() {
        let checkedKeys = this.$refs.menuTree.getCheckedKeys();
        let halfCheckedKeys = this.$refs.menuTree.getHalfCheckedKeys();
        checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
        return checkedKeys;
      },
      getDeptAllCheckedKeys() {
        let checkedKeys = this.$refs.dept.getCheckedKeys();
        let halfCheckedKeys = this.$refs.dept.getHalfCheckedKeys();
        checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
        return checkedKeys;
      },
      getRoleDeptTreeselect(roleId) {
        return roleTreeSelect(roleId).then((response) => {
          this.deptOptions = response.list;
          return response;
        });
      },
      handleStatusChange(row) {
        let text =
          row.status === 0 ?
          this.$t("user.Enable") :
          this.$t("user.Deactivate");
        this.$modal
          .confirm(
            this.$t("user.Sure") +
            text +
            '""' +
            row.roleName +
            this.$t("role.AreRole")
          )
          .then(function () {
            return changeRoleStatus(row.roleId, row.status);
          })
          .then(() => {
            this.$modal.msgSuccess(text + this.$t("user.Success"));
          }).catch(() => {
            row.status = row.status === 0 ? 1 : 0
          })
      },
      cancel() {
        this.open = false;
        this.reset();
      },
      cancelDataScope() {
        this.openDataScope = false;
        this.reset();
      },
      reset() {
        if (this.$refs.menuTree != undefined) {
          this.$refs.menuTree.setCheckedKeys([]);
        }
        (this.menuExpand = false),
        (this.menuNodeAll = false),
        (this.deptExpand = true),
        (this.deptNodeAll = false),
        (this.form = {
          roleId: undefined,
          roleName: undefined,
          roleKey: undefined,
          roleSort: 0,
          status: 0,
          menuIds: [],
          deptIds: [],
          menuCheckStrictly: true,
          deptCheckStrictly: true,
          remark: undefined,
        });
        this.resetForm("form");
      },
      handleQuery() {
        this.queryParams.pageNum = 1;
        this.getList();
      },
      resetQuery() {
        this.dateRange = [];
        this.resetForm("queryForm");
        this.handleQuery();
      },
      handleSelectionChange(selection) {
        this.ids = selection.map((item) => item.roleId);
        this.single = selection.length != 1;
        this.multiple = !selection.length;
      },
      handleCommand(command, row) {
        switch (command) {
          case "handleDataScope":
            this.handleDataScope(row);
            break;
          case "handleAuthUser":
            this.handleAuthUser(row);
            break;
          default:
            break;
        }
      },
      handleCheckedTreeExpand(value, type) {
        if (type == "menu") {
          let treeList = this.menuOptions;
          for (let i = 0; i < treeList.length; i++) {
            this.$refs.menuTree.store.nodesMap[treeList[i].id].expanded = value;
          }
        } else if (type == "dept") {
          let treeList = this.deptOptions;
          for (let i = 0; i < treeList.length; i++) {
            this.$refs.dept.store.nodesMap[treeList[i].id].expanded = value;
          }
        }
      },
      handleCheckedTreeNodeAll(value, type) {
        if (type == "menu") {
          this.$refs.menuTree.setCheckedNodes(value ? this.menuOptions : []);
        } else if (type == "dept") {
          this.$refs.dept.setCheckedNodes(value ? this.deptOptions : []);
        }
      },
      handleCheckedTreeConnect(value, type) {
        if (type == "menu") {
          this.form.menuCheckStrictly = value ? true : false;
        } else if (type == "dept") {
          this.form.deptCheckStrictly = value ? true : false;
        }
      },
      handleAdd() {
        this.reset();
        this.getMenuTreeselect();
        this.open = true;
        this.title = this.$t("role.AddRole");
      },
      handleUpdate(row) {
        this.reset();
        getRole(row.roleId).then((response) => {
          this.form = response.data;
          this.open = true;
          this.$nextTick(() => {
            roleMenuTreeselect(row.roleId).then((res) => {
              this.menuOptions = res.menus;
              let checkedKeys = res.checkedKeys;
              this.$nextTick(() => {
                checkedKeys.forEach((key) => {
                  this.$refs.menuTree.setChecked(key, true, false);
                });
              });
            });
          });
          this.title = this.$t("role.ModifyRole");
        });
      },
      dataScopeSelectChange(value) {
        if (value !== "2") {
          this.$refs.dept.setCheckedKeys([]);
        }
      },
      handleDataScope(row) {
        this.reset();
        const vm = this
        getRole(row.roleId).then((response) => {
          this.form = response.data;
          this.openDataScope = true;
          this.$nextTick(() => {
            vm.getRoleDeptTreeselect(row.roleId).then((res) => {
              this.$refs.dept.setCheckedKeys(res.checkedKeys);
            });
          });
          this.title = this.$t("role.AssignDataPermission");
        });
      },
      handleAuthUser: function (row) {
        const roleId = row.roleId;
        this.$router.push("/system/role-auth/user/" + roleId);
      },
      submitForm: function () {
        this.$refs["form"].validate((valid) => {
          if (valid) {
            if (this.form.roleId != undefined) {
              this.form.menuIds = this.getMenuAllCheckedKeys();
              updateRole(this.form).then((response) => {
                this.$modal.msgSuccess(this.$t("ModifySuccessful"));
                this.open = false;
                this.getList();
              });
            } else {
              this.form.menuIds = this.getMenuAllCheckedKeys();
              addRole(this.form).then((response) => {
                this.$modal.msgSuccess(this.$t("AddSuccessful"));
                this.open = false;
                this.getList();
              });
            }
          }
        });
      },
      submitDataScope: function () {
        if (this.form.roleId != undefined) {
          this.form.deptIds = this.getDeptAllCheckedKeys();
          dataScope(this.form).then((response) => {
            this.$modal.msgSuccess(this.$t("ModifySuccessful"));
            this.openDataScope = false;
            this.getList();
          });
        }
      },
      handleDelete(row) {
        const roleIds = row.roleId || this.ids;
        this.$modal
          .confirm(this.$t("common.SureDelete"))
          .then(function () {
            return delRole(roleIds);
          })
          .then(() => {
            this.getList();
            this.$modal.msgSuccess(this.$t("DeleteSuccessful"));
          })
          .catch(() => {});
      },
      handleExport() {
        this.download(
          "system/role/export", {
            ...this.queryParams,
          },
          `role_${new Date().getTime()}.xlsx`
        );
      },
    },
  };

</script>
